using System;
using System.Collections.Generic;
using System.Text;
using Microformats.Readers;
using System.Text.RegularExpressions;

namespace Microformats.Helpers
{
    /// <summary>
    /// The encoding class contains function that replicate the some of the System.Web functionality for encoding and decoding data in html.
    /// </summary>
    internal class Encoding: IEncoder
    {
        private InputSourceType encodingType;
        private IEncoder entityEncoder;

        /// <summary>
        /// Creates an instance of the Encoding class that can work either with HTML entities or XML entities.
        /// </summary>
        /// <param name="encodingType">The type of encoding.</param>
        public Encoding(InputSourceType encodingType)
        {
            this.encodingType = encodingType;

            if (encodingType == InputSourceType.Html)
            {
                entityEncoder = new HtmlEntityEncoder();
            }
            else
            {
                entityEncoder = new XmlEntityEncoder();
            }

        }

        /// <summary>
        /// Encodes a string into data that is HTML encoded
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string Encode(string input)
        {
            return entityEncoder.Encode(input);
        }

        /// <summary>
        /// Decodes HTML encoded elements into a non encoded string
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string Decode(string input)
        {
            return entityEncoder.Decode(input) ;
        }
    }

    internal interface IEncoder
    {
        string Encode(string input);
        string Decode(string input);
    }

    /// <summary>
    /// Encodes and Decodes XML Entities
    /// </summary>
    internal class XmlEntityEncoder: IEncoder
    {
        #region IEncoder Members

        /// <summary>
        /// Encodes the 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string Encode(string input)
        {
            input = input.Replace("\"", "&quot;");
            input = input.Replace("\'", "&apos;");
            input = input.Replace("<", "&lt;");
            input = input.Replace(">", "&gt;");

            //Replace lone ampersands or un-ended &amp codes with &amp;
            Regex r = new Regex("&(?!([^;]*?);)", RegexOptions.IgnoreCase);
            input = r.Replace(input, "&amp;");

            return input;
        }

        public string Decode(string input)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }

    /// <summary>
    /// Encodes and Decodes HtmlEntities.
    /// </summary>
    internal class HtmlEntityEncoder: IEncoder
    {
        #region IEncoder Members

        public string Encode(string input)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public string Decode(string input)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }
}
